package cz.kfad.ofrss.rss;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;

import org.mcsoxford.rss.RSSFeed;
import org.mcsoxford.rss.RSSItem;
import org.mcsoxford.rss.RSSReader;
import org.mcsoxford.rss.RSSReaderException;

import android.content.Context;
import cz.kfad.ofrss.backend.BackendService;
import cz.kfad.ofrss.db.DatabaseHelper;
import cz.kfad.ofrss.model.Channel;
import cz.kfad.ofrss.model.RssFeed;

public class RssFetcherImpl implements RssFetcher {

    private final Context context;

    public RssFetcherImpl(Context context) {
        this.context = context;
    }

    @Override
    public void fetchAllChannels() {
        final RSSReader rssReader = new RSSReader();
        final List<Channel> allChannels = BackendService.createBackend(context).findAllChannels();

        for (Channel channel : allChannels) {
            try {
                final RSSFeed rssFeed = rssReader.load(channel.getUrl());
                final List<RSSItem> items = rssFeed.getItems();
                proceedRssItems(items, channel.getId());
            } catch (Exception e) {
                e.printStackTrace();
                continue;
            }
			// } catch (UnknownHostException e1) {
			// e1.printStackTrace();
			// continue;
			// } catch (RSSReaderException e) {
			// e.printStackTrace();
			// continue;
			// }

        }
    }

    private void proceedRssItems(List<RSSItem> items, int channelId) {
        final DatabaseHelper databaseHelper = new DatabaseHelper(context);
        final List<RssFeed> rssFeeds = new ArrayList<RssFeed>();
        Collections.sort(rssFeeds, new Comparator<RssFeed>() {

            @Override
            public int compare(RssFeed lhs, RssFeed rhs) {
                return lhs.getDate().compareTo(rhs.getDate());
            }

        });

        final Channel channel = databaseHelper.findChannelById(channelId);
        final Date newestFetched = channel.getNewestFetched();

        for (RSSItem item : items) {
            final RssFeed rssFeed = convertRSSItemToRssFeed(item, channelId);
            if (!newestFetched.before(rssFeed.getDate())) {
                // if (databaseHelper.containsRssFeed(rssFeed.getHash())) {
                break;
            }
            rssFeeds.add(rssFeed);
        }
        if (!rssFeeds.isEmpty()) {
            databaseHelper.saveRssFeeds(rssFeeds);
            databaseHelper.increaseCountsForChannel(channelId, rssFeeds.size());
            databaseHelper.saveNewestFetched(channelId, rssFeeds.get(0).getDate());
        }
    }

    private RssFeed convertRSSItemToRssFeed(RSSItem item, int channelId) {
        final RssFeed rssFeed = new RssFeed();
        rssFeed.setUrl(item.getLink().toString());
        rssFeed.setTitle(item.getTitle());
        rssFeed.setText(item.getDescription().replaceAll(Pattern.quote("<") + ".*?" + Pattern.quote(">"), "").replace("&nbsp;", ""));
        rssFeed.setDate(item.getPubDate());
        rssFeed.setChannelId(channelId);
        rssFeed.setHash(rssFeed.hashCode());
        return rssFeed;
    }

    @Override
    public boolean testUrl(String url) {
        final RSSReader rssReader = new RSSReader();
        try {
            rssReader.load(url);
            return true;
        } catch (RSSReaderException e) {
            return false;
        }
    }

    @Override
    public void fetchChannel(Channel channel) {
        try {
            final RSSReader rssReader = new RSSReader();
            final RSSFeed rssFeed = rssReader.load(channel.getUrl());
            final List<RSSItem> items = rssFeed.getItems();
            final int size = items.size();
            channel.setTotalFeeds(size);
            channel.setUnreadFeeds(size);
            proceedRssItems(items, channel.getId());
		} catch (Exception e) {
            e.printStackTrace();
        }
    }
}
